package com.jule.teenpatti.game.network.protocol.reqs;

import JoloProtobuf.GameSvr.JoloGame;
import com.jule.core.common.log.LoggerUtils;
import com.jule.teenpatti.base.enums.ErrorCodeEnum;
import com.jule.teenpatti.base.enums.GameConst;
import com.jule.teenpatti.game.model.PlayerInfo;
import com.jule.teenpatti.game.model.eenum.PlayerStateEnum;
import com.jule.teenpatti.base.enums.TableStateEnum;
import com.jule.teenpatti.game.network.protocol.ClientReq;
import com.jule.teenpatti.game.network.protocol.acks.JoloGame_ApplyLeaveAck_50003;
import com.jule.teenpatti.game.network.protocol.logic.LeaveTableLogic;
import com.jule.teenpatti.game.play.AbstractTable;
import com.jule.teenpatti.game.play.TableUtil;
import com.jule.teenpatti.game.service.PlayerService;
import com.jule.teenpatti.game.service.TableService;
import io.netty.buffer.ByteBuf;
import lombok.extern.slf4j.Slf4j;

/**
 * 申请离桌
 */
@Slf4j
public class JoloGame_ApplyLeaveReq_50003 extends ClientReq {

    private long time;

    public JoloGame_ApplyLeaveReq_50003(int functionId) {
        super(functionId);
    }

    private JoloGame.JoloGame_ApplyLeaveReq req;

    @Override
    public void readPayLoadImpl(ByteBuf buf) throws Exception {
        time = System.currentTimeMillis();
        byte[] blob = new byte[buf.readableBytes()];
        buf.readBytes(blob);
        req = JoloGame.JoloGame_ApplyLeaveReq.parseFrom(blob);
        this.setTable(TableService.getInstance().getTable(header.gameId + "", req.getRoomId(), req.getTableId()));
    }

    @Override
    public void processImpl() throws Exception {
        log.debug("收到消息-> " + functionId + " reqNum-> " + header.reqNum + "req->" + req.toString());
        JoloGame.JoloGame_ApplyLeaveAck.Builder ack = JoloGame.JoloGame_ApplyLeaveAck.newBuilder();
        String userId = req.getUserId();
        AbstractTable table = null;
        try {
            ack.setUserId(req.getUserId());
            ack.setRoomId(req.getRoomId());
            ack.setTableId(req.getTableId());
            ack.setResult(1);


            PlayerService.getInstance().onPlayerLoutOut("" + userId);
            table = getTable();
            if (table == null) {
                log.error("table is null ");
                ack.setResult(-2).setResultMsg("请在游戏结束后退出！");
                ctx.writeAndFlush(new JoloGame_ApplyLeaveAck_50003(ack.build(), header));
                return;
            }
            PlayerInfo player = table.getPlayer(userId);


            if (null == player) {
                log.debug("can't found player info, playerId->" + userId);
                ack.setResult(1).setResultMsg(ErrorCodeEnum.GAME_50050_2.getCode()); //modify by gx 20181010 resut=1,因为找不到玩家信息，可以返回大厅，不影响逻辑。
                ctx.writeAndFlush(new JoloGame_ApplyLeaveAck_50003(ack.build(), header));
                return;
            }

            //玩家游戏中不许离开
            log.debug("玩家的状态："+player.getState()+" 桌子的状态："+table.getTableStateEnum());
            if(player.getState() != PlayerStateEnum.fold && player.getState() != PlayerStateEnum.siteDown
                    && player.getState() != PlayerStateEnum.showfail
                    && table.getTableStateEnum() != TableStateEnum.GAME_START
                    && table.getTableStateEnum() != TableStateEnum.SETTLE
                    && table.getTableStateEnum() != TableStateEnum.IDEL){
                log.info("can't quit this game. gameId->{}, roomId->{}, tableId->{}, userId->{}",
                        header.gameId, table.getRoomId(), table.getTableId(), userId);
                ack.setResult(-2).setResultMsg("请在游戏结束后退出！");
                ctx.writeAndFlush(new JoloGame_ApplyLeaveAck_50003(ack.build(), header));
                return;
            }

            LeaveTableLogic.getInstance().logic(player, table, ack);

            //输出结果给客户端
            ctx.writeAndFlush(new JoloGame_ApplyLeaveAck_50003(ack.build(), header));
            long timeMillis = System.currentTimeMillis() - time;
            if (timeMillis > GameConst.COST_TIME) {
                LoggerUtils.performance.info("ApplyLeaveReq_50003,cost time:{},req:{}", timeMillis, req.toString());
            }
        } catch (Exception ex) {
            ack.setResult(-10).setResultMsg(ErrorCodeEnum.GAME_50002_2.getCode());
            ack.setCurrStoreScore(0);
            ctx.writeAndFlush(new JoloGame_ApplyLeaveAck_50003(ack.build(), header));
            log.error("", ex);
        } finally {
            log.debug("Leave ACK info: " + ack.toString());
            log.debug("Leave ACK bytes length: " + ack.build().toByteArray().length);
            if (null != table) {
                log.debug("All Player info: " + System.getProperty("line.separator") + TableUtil.toStringAllPlayers(table));

                log.debug("InGame Player info: " + System.getProperty("line.separator") + TableUtil.toStringInGamePlayers(table));

                log.debug("Leave over. Table state: " + table.getTableStateEnum());
            }

            long useTimes = System.currentTimeMillis() - time;
            if(useTimes > 500) {
                log.error("ApplyLeave。 耗时->{} 毫秒, reqNum->{}", useTimes, header.reqNum); //TODO:临时增加
            }
        }
    }
}
